home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / usr / include / nspr / plarena.h < prev    next >
C/C++ Source or Header  |  2006-04-20  |  8KB  |  214 lines

  1. /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
  2. /* ***** BEGIN LICENSE BLOCK *****
  3.  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  4.  *
  5.  * The contents of this file are subject to the Mozilla Public License Version
  6.  * 1.1 (the "License"); you may not use this file except in compliance with
  7.  * the License. You may obtain a copy of the License at
  8.  * http://www.mozilla.org/MPL/
  9.  *
  10.  * Software distributed under the License is distributed on an "AS IS" basis,
  11.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  12.  * for the specific language governing rights and limitations under the
  13.  * License.
  14.  * 
  15.  * The Original Code is the Netscape Portable Runtime (NSPR).
  16.  * 
  17.  * The Initial Developer of the Original Code is Netscape
  18.  * Communications Corporation.  Portions created by Netscape are 
  19.  * Copyright (C) 1998-2000 Netscape Communications Corporation.  All
  20.  * Rights Reserved.
  21.  * 
  22.  * Contributor(s):
  23.  *
  24.  * Alternatively, the contents of this file may be used under the terms of
  25.  * either the GNU General Public License Version 2 or later (the "GPL"), or
  26.  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  27.  * in which case the provisions of the GPL or the LGPL are applicable instead
  28.  * of those above. If you wish to allow use of your version of this file only
  29.  * under the terms of either the GPL or the LGPL, and not to allow others to
  30.  * use your version of this file under the terms of the MPL, indicate your
  31.  * decision by deleting the provisions above and replace them with the notice
  32.  * and other provisions required by the GPL or the LGPL. If you do not delete
  33.  * the provisions above, a recipient may use your version of this file under
  34.  * the terms of any one of the MPL, the GPL or the LGPL.
  35.  *
  36.  * ***** END LICENSE BLOCK *****
  37.  */
  38.  
  39. #ifndef plarena_h___
  40. #define plarena_h___
  41. /*
  42.  * Lifetime-based fast allocation, inspired by much prior art, including
  43.  * "Fast Allocation and Deallocation of Memory Based on Object Lifetimes"
  44.  * David R. Hanson, Software -- Practice and Experience, Vol. 20(1).
  45.  *
  46.  * Also supports LIFO allocation (PL_ARENA_MARK/PL_ARENA_RELEASE).
  47.  */
  48. #include "prtypes.h"
  49. #include "plarenas.h"
  50.  
  51. PR_BEGIN_EXTERN_C
  52.  
  53. typedef struct PLArena          PLArena;
  54.  
  55. struct PLArena {
  56.     PLArena     *next;          /* next arena for this lifetime */
  57.     PRUword     base;           /* aligned base address, follows this header */
  58.     PRUword     limit;          /* one beyond last byte in arena */
  59.     PRUword     avail;          /* points to next available byte */
  60. };
  61.  
  62. #ifdef PL_ARENAMETER
  63. typedef struct PLArenaStats PLArenaStats;
  64.  
  65. struct PLArenaStats {
  66.     PLArenaStats  *next;        /* next in arenaStats list */
  67.     char          *name;        /* name for debugging */
  68.     PRUint32      narenas;      /* number of arenas in pool */
  69.     PRUint32      nallocs;      /* number of PL_ARENA_ALLOCATE() calls */
  70.     PRUint32      nreclaims;    /* number of reclaims from freeArenas */
  71.     PRUint32      nmallocs;     /* number of malloc() calls */
  72.     PRUint32      ndeallocs;    /* number of lifetime deallocations */
  73.     PRUint32      ngrows;       /* number of PL_ARENA_GROW() calls */
  74.     PRUint32      ninplace;     /* number of in-place growths */
  75.     PRUint32      nreleases;    /* number of PL_ARENA_RELEASE() calls */
  76.     PRUint32      nfastrels;    /* number of "fast path" releases */
  77.     PRUint32      nbytes;       /* total bytes allocated */
  78.     PRUint32      maxalloc;     /* maximum allocation size in bytes */
  79.     PRFloat64     variance;     /* size variance accumulator */
  80. };
  81. #endif
  82.  
  83. struct PLArenaPool {
  84.     PLArena     first;          /* first arena in pool list */
  85.     PLArena     *current;       /* arena from which to allocate space */
  86.     PRUint32    arenasize;      /* net exact size of a new arena */
  87.     PRUword     mask;           /* alignment mask (power-of-2 - 1) */
  88. #ifdef PL_ARENAMETER
  89.     PLArenaStats stats;
  90. #endif
  91. };
  92.  
  93. /*
  94.  * If the including .c file uses only one power-of-2 alignment, it may define
  95.  * PL_ARENA_CONST_ALIGN_MASK to the alignment mask and save a few instructions
  96.  * per ALLOCATE and GROW.
  97.  */
  98. #ifdef PL_ARENA_CONST_ALIGN_MASK
  99. #define PL_ARENA_ALIGN(pool, n) (((PRUword)(n) + PL_ARENA_CONST_ALIGN_MASK) \
  100.                                 & ~PL_ARENA_CONST_ALIGN_MASK)
  101.  
  102. #define PL_INIT_ARENA_POOL(pool, name, size) \
  103.         PL_InitArenaPool(pool, name, size, PL_ARENA_CONST_ALIGN_MASK + 1)
  104. #else
  105. #define PL_ARENA_ALIGN(pool, n) (((PRUword)(n) + (pool)->mask) & ~(pool)->mask)
  106. #endif
  107.  
  108. #define PL_ARENA_ALLOCATE(p, pool, nb) \
  109.     PR_BEGIN_MACRO \
  110.         PLArena *_a = (pool)->current; \
  111.         PRUint32 _nb = PL_ARENA_ALIGN(pool, nb); \
  112.         PRUword _p = _a->avail; \
  113.         PRUword _q = _p + _nb; \
  114.         if (_q > _a->limit) \
  115.             _p = (PRUword)PL_ArenaAllocate(pool, _nb); \
  116.         else \
  117.             _a->avail = _q; \
  118.         p = (void *)_p; \
  119.         PL_ArenaCountAllocation(pool, nb); \
  120.     PR_END_MACRO
  121.  
  122. #define PL_ARENA_GROW(p, pool, size, incr) \
  123.     PR_BEGIN_MACRO \
  124.         PLArena *_a = (pool)->current; \
  125.         PRUint32 _incr = PL_ARENA_ALIGN(pool, incr); \
  126.         PRUword _p = _a->avail; \
  127.         PRUword _q = _p + _incr; \
  128.         if (_p == (PRUword)(p) + PL_ARENA_ALIGN(pool, size) && \
  129.             _q <= _a->limit) { \
  130.             _a->avail = _q; \
  131.             PL_ArenaCountInplaceGrowth(pool, size, incr); \
  132.         } else { \
  133.             p = PL_ArenaGrow(pool, p, size, incr); \
  134.         } \
  135.         PL_ArenaCountGrowth(pool, size, incr); \
  136.     PR_END_MACRO
  137.  
  138. #define PL_ARENA_MARK(pool) ((void *) (pool)->current->avail)
  139. #define PR_UPTRDIFF(p,q) ((PRUword)(p) - (PRUword)(q))
  140.  
  141. #ifdef DEBUG
  142. #define PL_FREE_PATTERN 0xDA
  143. #define PL_CLEAR_UNUSED(a) (PR_ASSERT((a)->avail <= (a)->limit), \
  144.                            memset((void*)(a)->avail, PL_FREE_PATTERN, \
  145.                            (a)->limit - (a)->avail))
  146. #define PL_CLEAR_ARENA(a)  memset((void*)(a), PL_FREE_PATTERN, \
  147.                            (a)->limit - (PRUword)(a))
  148. #else
  149. #define PL_CLEAR_UNUSED(a)
  150. #define PL_CLEAR_ARENA(a)
  151. #endif
  152.  
  153. #define PL_ARENA_RELEASE(pool, mark) \
  154.     PR_BEGIN_MACRO \
  155.         char *_m = (char *)(mark); \
  156.         PLArena *_a = (pool)->current; \
  157.         if (PR_UPTRDIFF(_m, _a->base) <= PR_UPTRDIFF(_a->avail, _a->base)) { \
  158.             _a->avail = (PRUword)PL_ARENA_ALIGN(pool, _m); \
  159.             PL_CLEAR_UNUSED(_a); \
  160.             PL_ArenaCountRetract(pool, _m); \
  161.         } else { \
  162.             PL_ArenaRelease(pool, _m); \
  163.         } \
  164.         PL_ArenaCountRelease(pool, _m); \
  165.     PR_END_MACRO
  166.  
  167. #ifdef PL_ARENAMETER
  168. #define PL_COUNT_ARENA(pool,op) ((pool)->stats.narenas op)
  169. #else
  170. #define PL_COUNT_ARENA(pool,op)
  171. #endif
  172.  
  173. #define PL_ARENA_DESTROY(pool, a, pnext) \
  174.     PR_BEGIN_MACRO \
  175.         PL_COUNT_ARENA(pool,--); \
  176.         if ((pool)->current == (a)) (pool)->current = &(pool)->first; \
  177.         *(pnext) = (a)->next; \
  178.         PL_CLEAR_ARENA(a); \
  179.         free(a); \
  180.         (a) = 0; \
  181.     PR_END_MACRO
  182.  
  183. #ifdef PL_ARENAMETER
  184.  
  185. #include <stdio.h>
  186.  
  187. PR_EXTERN(void) PL_ArenaCountAllocation(PLArenaPool *pool, PRUint32 nb);
  188.  
  189. PR_EXTERN(void) PL_ArenaCountInplaceGrowth(
  190.     PLArenaPool *pool, PRUint32 size, PRUint32 incr);
  191.  
  192. PR_EXTERN(void) PL_ArenaCountGrowth(
  193.     PLArenaPool *pool, PRUint32 size, PRUint32 incr);
  194.  
  195. PR_EXTERN(void) PL_ArenaCountRelease(PLArenaPool *pool, char *mark);
  196.  
  197. PR_EXTERN(void) PL_ArenaCountRetract(PLArenaPool *pool, char *mark);
  198.  
  199. PR_EXTERN(void) PL_DumpArenaStats(FILE *fp);
  200.  
  201. #else  /* !PL_ARENAMETER */
  202.  
  203. #define PL_ArenaCountAllocation(ap, nb)                 /* nothing */
  204. #define PL_ArenaCountInplaceGrowth(ap, size, incr)      /* nothing */
  205. #define PL_ArenaCountGrowth(ap, size, incr)             /* nothing */
  206. #define PL_ArenaCountRelease(ap, mark)                  /* nothing */
  207. #define PL_ArenaCountRetract(ap, mark)                  /* nothing */
  208.  
  209. #endif /* !PL_ARENAMETER */
  210.  
  211. PR_END_EXTERN_C
  212.  
  213. #endif /* plarena_h___ */
  214.